﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using VNet.VisiSuite.Common.Helper;
using VNet.VisiSuite.Controls;
using VNet.VisiSuite.Service.Contact.Message.Security;
using VNet.VisiSuite.Service.Contact.Message.Base;
using VNet.VisiSuite.VisiCentral.Common;
using VNet.VisiSuite.VisiCentral.Common.Helpers;
using VNet.VisiSuite.VisiCentral.Models;
using VNet.VisiSuite.VisiCentral.Providers;
using VNet.VisiSuite.VisiCentral.Views;
using VNet.VisiSuite.Service.Contact.Message.Item;
using VNet.VisiSuite.Common.Resource;
using VNet.VisiSuite.Service.Contact.Enum;
using System.Windows;
using VNet.VisiSuite.Common;
using System.Windows.Media;
using System.Windows.Threading;

using VNet.VisiSuite.Common.Logger;
using VNet.VisiSuite.Common.Production;
using VNet.VisiSuite.Service.Contact.Message;
using VNet.VisiSuite.Service.Contact.Message.ProductionData;

namespace VNet.VisiSuite.VisiCentral.ViewModels
{
    public class MainViewModel : BaseViewModel, VNet.VisiSuite.Common.Production.ProductionInterface
    {
        #region Fields

        int _area_id = 13;  // BOGUS HARDCODED
        CellViewModel _selected_cell = null;
        CellViewMode _cell_view_mode = CellViewMode.None;

        List<CellViewModel> _cells_group1 = new List<CellViewModel>();
        List<CellViewModel> _cells_group2 = new List<CellViewModel>();
        List<CellViewModel> _cells_group3 = new List<CellViewModel>();
        List<CellViewModel> _all_cells = new List<CellViewModel>();

        public const string DEFAULT_COLOR_CELL = "#FF766867";
        public const string DEFAULT_CELL_COLOR = "#e3e3e3";
        public const string CANNOT_NAVIGATE_TO_FUTURE_SHIFT = "Cannot navigate to future shift";

        CellProductionData _cell_production_data;
        AreaProductionData _area_production_data;

        List<ProductionMeterGraphLegend> _legend;

        DispatcherTimer _refresh_ui_timer;
        bool _refreshing_ui = false;

        enum CellViewMode
        {
            None = 0,
            Production = 1,
            Downtime = 2
        }

        private DateTime _shiftDate;
        private DateTime _maxShiftDate;
        private AreaShiftItem _selectedAreaShift;
        private IList<AreaShiftItem> _shiftList = new List<AreaShiftItem>();
        private bool _selectedCurrentShift;

        #endregion

        public MainViewModel()
        {
            PageTitle = TitleString.MainViewCentralTitle;

            TopRightButtonIcons = new ObservableCollection<VNetMenuItem> { new VNetMenuItem(null, "Logout VisiCentral", CommonConstants.VNetIcon.AppbarDoorLeave, VNetMenuItemType.WhiteBackgroundTheme, OnLogout) };

            var appCloseMenuItem = new VNetMenuItem(TitleString.Main_BottomMenuTitleClose, TitleString.Main_BottomMenuTooltipClose, Constants.VNetIcon.AppbarClose, VNetMenuItemType.WhiteBackgroundBlackIconTheme, OnExit, "10", Visibility.Visible, "50 0 0 0");
            var analysisViewMenuItem = new VNetMenuItem(TitleString.Main_BottomMenuTitleAnalysisView, TitleString.Main_BottomMenuTooltipAnalysisView, Constants.VNetIcon.AppbarGraphBar, VNetMenuItemType.WhiteBackgroundBlackIconTheme, OnAnalysis);
            var bottomMenuItems = new ObservableCollection<VNetMenuItem>();
            bottomMenuItems.Add(analysisViewMenuItem);
            bottomMenuItems.Add(appCloseMenuItem);
            BottomMenuItems = bottomMenuItems;

            // Set default date time for ShiftDate
            MaxShiftDate = DateTime.Now.Date;
            
            NextShiftCommand = new RelayCommand(OnNextShift);
            PreviousShiftCommand = new RelayCommand(OnPreviousShift);

            _refresh_ui_timer = new DispatcherTimer(DispatcherPriority.ContextIdle, Dispatcher.CurrentDispatcher)
            {
                Interval = new TimeSpan(0, 0, 0, 15, 0)
            };
            _refresh_ui_timer.Tick += refreshUi;

        }

        ~MainViewModel()
        {
            // Cleaning up
            _refresh_ui_timer.Stop();
            _refresh_ui_timer.Tick -= refreshUi;
        }

        #region Properties

        public DateTime ShiftDate {
            get
            {
                return _shiftDate;
            }
            set
            {
                // Validate if it is a future shift + date before saving
                // Store the current value so that we can change it back if needed.
                var origValue = _shiftDate;
                // If the value hasn't changed, don't do anything.
                if (value == _shiftDate)
                    return;

                // Validate selected area shift to make sure user cannot select future shift and date
                _shiftDate = value;
                var currentDateTime = DateTime.Now;
                if (ShiftList.Count > 0 && SelectedAreaShift != null)
                if (ShiftDate.Date.Add(SelectedAreaShift.StartTime) 
                    > currentDateTime && ShiftDate.Date == currentDateTime.Date)
                {
                    // Change the selected area shift to current shift, but do so after the 
                    // UI has finished it's current context operation.
                    var currentShift = GetCurrentAreaShiftItem(ShiftList);

                    // Incase the current shift and selected date still in the future, revert the selected date,
                    // Other wise, change the selected shift to current shift.
                    if (ShiftDate.Date.Add(currentShift.StartTime)
                        > currentDateTime && ShiftDate.Date == currentDateTime.Date)
                    {
                        Application.Current.Dispatcher.BeginInvoke(
                            new Action(() =>
                            {
                                _shiftDate = origValue;
                                OnPropertyChanged("ShiftDate");
                                SetSelectedCurrentShift(_selectedAreaShift, ShiftDate);
                                refreshUi(null, null);
                            }),
                            DispatcherPriority.ContextIdle,
                            null
                        );
                    }
                    else
                    {
                        Application.Current.Dispatcher.BeginInvoke(
                            new Action(() =>
                            {
                                _selectedAreaShift = currentShift;
                                OnPropertyChanged("SelectedAreaShift");
                                SetSelectedCurrentShift(_selectedAreaShift, ShiftDate);
                                refreshUi(null, null);
                            }),
                            DispatcherPriority.ContextIdle,
                            null
                        );
                    }
                }
                else
                {
                    OnPropertyChanged("ShiftDate");
                    SetSelectedCurrentShift(_selectedAreaShift, ShiftDate);
                    refreshUi(null, null);
                }
            }
        }

        public DateTime MaxShiftDate
        {
            get { return _maxShiftDate; }
            set { 
                _maxShiftDate = value;
                OnPropertyChanged("MaxShiftDate");
            }
        }

        public AreaShiftItem SelectedAreaShift
        {
            get
            {
                return _selectedAreaShift;
            }
            set
            {
                // Validate if it is a future shift before saving
                // Store the current value so that we can change it back if needed.
                var origValue = _selectedAreaShift;
                // If the value hasn't changed, don't do anything.
                if (value == _selectedAreaShift)
                    return;

                // Note that we actually change the value for now.
                // This is necessary because WPF seems to query the 
                //  value after the change. The combo box
                // likes to know that the value did change.
                _selectedAreaShift = value;
                OnPropertyChanged("SelectedAreaShift");
                var currentDateTime = DateTime.Now;

                if (ShiftDate.Date.Add(value.StartTime) > currentDateTime && ShiftDate.Date == currentDateTime.Date
                    && origValue != null)
                {
                    MessageBox.Show(
                        CANNOT_NAVIGATE_TO_FUTURE_SHIFT,
                        "Error",
                        MessageBoxButton.OK
                    );

                    // change the value back, but do so after the 
                    // UI has finished it's current context operation.
                    Application.Current.Dispatcher.BeginInvoke(
                            new Action(() =>
                            {
                                _selectedAreaShift = origValue;
                                OnPropertyChanged("SelectedAreaShift");
                                SetSelectedCurrentShift(_selectedAreaShift, ShiftDate);
                                refreshUi(null, null);
                            }),
                            DispatcherPriority.ContextIdle,
                            null
                    );
                }
                else
                {
                    SetSelectedCurrentShift(_selectedAreaShift, ShiftDate);
                    refreshUi(null, null);
                }
            }
        }

        public IList<AreaShiftItem> ShiftList {
            get
            {
                if (!_shiftList.Any())
                {
                    IsBusy = true;
                    DoAsync(VisiCentralProvider.GetAreaShifts, GetAreaShiftsCompleted, _area_id);
                }
                return _shiftList;
            }
            set
            {
                _shiftList = value;
                OnPropertyChanged("ShiftList");
            }
        }

        public RelayCommand PreviousShiftCommand { get; set; }
        public RelayCommand NextShiftCommand { get; set; }

        public List<CellViewModel> CellGroup1
        {
            get
            {
                if (!_cells_group1.Any())
                {
                    IsBusy = true;
                    DoAsync(VisiCentralProvider.GetCells, GetCellsCompleted, _area_id);
                }
                return _cells_group1;
            }
            set
            {
                _cells_group1 = value;
                OnPropertyChanged("CellGroup1");
            }
        }

        public List<CellViewModel> CellGroup2
        {
            get
            {
                return _cells_group2;
            }
            set
            {
                _cells_group2 = value;
                OnPropertyChanged("CellGroup2");
            }
        }

        public List<CellViewModel> CellGroup3
        {
            get
            {
                return _cells_group3;
            }
            set
            {
                _cells_group3 = value;
                OnPropertyChanged("CellGroup3");
            }
        }

        public Visibility ShowCellProductionControls { get { return _cell_view_mode == CellViewMode.Production ? Visibility.Visible : Visibility.Collapsed; } }
        public Visibility ShowAreaProductionControls { get { return _cell_view_mode != CellViewMode.Production ? Visibility.Visible : Visibility.Collapsed; } }

        #endregion

        #region Methods

        #region Callback methods

        private void OnLogout()
        {
            IsBusy = true;
            DoAsync(SecurityProvider.Logout, LogoutCompleted);
        }
        private void LogoutCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as SignOutResponse;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    ErrorMessage = response.Error.Description;
                return;
            }

            NavigationManager.LoggedInUser = null;
            FileHelper.DeleteAllFilesInFolder();
            NavigationManager.NavigateTo(new LoginView(), true);
        }

        private void GetCellsCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as GetDataResponse<IList<CellItem>>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    ErrorMessage = response.Error.Description;
                return;
            }

            var cells = response.Data;
            var cvms1 = new List<CellViewModel>();
            var cvms2 = new List<CellViewModel>();
            var cvms3 = new List<CellViewModel>();

            int prev_idx = -1;
            int this_idx = 0;
            int ii = 0;
            foreach (var cell in cells)
            {
                if (cell.VisiCentralGroup == 1 && cell.VisiCentralRow > 0 && cell.VisiCentralRow < 6 && cell.VisiCentralColumn > 0 && cell.VisiCentralColumn < 11)
                {
                    this_idx = (cell.VisiCentralRow - 1) * 10 + (cell.VisiCentralColumn - 1);
                    for (ii = prev_idx + 1; ii < this_idx; ++ii)
                    {
                        cvms1.Add(new CellViewModel("0", 0, Brushes.Transparent.ToString(), Brushes.Transparent.ToString(), DEFAULT_CELL_COLOR, DEFAULT_CELL_COLOR, false, false));
                    }
                    cvms1.Add(new CellViewModel(cell.Description, cell.CellId, Brushes.Transparent.ToString(), Brushes.Transparent.ToString(), DEFAULT_CELL_COLOR, DEFAULT_CELL_COLOR, true, false));
                    prev_idx = this_idx;
                }

                if (cell.VisiCentralGroup == 2 && cell.VisiCentralRow > 0 && cell.VisiCentralRow < 6 && cell.VisiCentralColumn > 0 && cell.VisiCentralColumn < 11)
                {
                    if (!cvms2.Any())
                        prev_idx = -1;

                    this_idx = (cell.VisiCentralRow - 1) * 10 + (cell.VisiCentralColumn - 1);
                    for (ii = prev_idx + 1; ii < this_idx; ++ii)
                    {
                        cvms2.Add(new CellViewModel("0", 0, Brushes.Transparent.ToString(), Brushes.Transparent.ToString(), DEFAULT_CELL_COLOR, DEFAULT_CELL_COLOR, false, false));
                    }
                    cvms2.Add(new CellViewModel(cell.Description, cell.CellId, Brushes.Transparent.ToString(), Brushes.Transparent.ToString(), DEFAULT_CELL_COLOR, DEFAULT_CELL_COLOR, true, false));
                    prev_idx = this_idx;
                }

                if (cell.VisiCentralGroup == 3 && cell.VisiCentralRow > 0 && cell.VisiCentralRow < 6 && cell.VisiCentralColumn > 0 && cell.VisiCentralColumn < 10)
                {
                    if (!cvms3.Any())
                        prev_idx = -1;

                    this_idx = (cell.VisiCentralRow - 1) * 9 + (cell.VisiCentralColumn - 1);
                    for (ii = prev_idx + 1; ii < this_idx; ++ii)
                    {
                        cvms3.Add(new CellViewModel("0", 0, Brushes.Transparent.ToString(), Brushes.Transparent.ToString(), DEFAULT_CELL_COLOR, DEFAULT_CELL_COLOR, false, false));
                    }
                    cvms3.Add(new CellViewModel(cell.Description, cell.CellId, Brushes.Transparent.ToString(), Brushes.Transparent.ToString(), DEFAULT_CELL_COLOR, DEFAULT_CELL_COLOR, true, false));
                    prev_idx = this_idx;
                }
            }

            CellGroup1 = cvms1;
            CellGroup2 = cvms2;
            CellGroup3 = cvms3;
            _all_cells = cvms1.Concat(cvms2).Concat(cvms3).ToList();

            refreshUi(null, null);

        }

        private void GetCellProductionDataCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
                return;

            var response = e.Result as ProductionDataResponse;
            _refreshing_ui = false;
            _refresh_ui_timer.Start();

            if (response == null || !response.Success)
            {
                if (response != null)
                {
                    ErrorMessage = response.Error.Description;
                    FileLog.Error("GetCellProductionDataCompleted() - " + response.Error.Description);
                }
                return;
            }

            _cell_production_data = response.CellProductionData;
            if (_cell_production_data != null)
            {
                OnPropertyChanged("CurrentSku");
                OnPropertyChanged("NextSku");
                OnPropertyChanged("CurrentWorkOrder");
                OnPropertyChanged("NextWorkOrder");
                OnPropertyChanged("CurrentPass");
                OnPropertyChanged("NextPass");
                OnPropertyChanged("CurrentQuantity");
                OnPropertyChanged("NextQuantity");
                OnPropertyChanged("CurrentRemaining");
                OnPropertyChanged("NextRemaining");

                OnPropertyChanged("Operator");

                OnPropertyChanged("TargetCycleTime");
                OnPropertyChanged("AverageCycleTime");
                OnPropertyChanged("TargetLoadUnloadTime");
                OnPropertyChanged("AverageLoadUnloadTime");

                _legend = new List<ProductionMeterGraphLegend>();
                if (_cell_production_data != null)
                {
                    foreach (var lgd in _cell_production_data.Legend)
                    {
                        _legend.Add(new ProductionMeterGraphLegend(lgd.Description, new SolidColorBrush(Infragistics.ColorConverter.FromString(lgd.Color))));
                    }
                }

                OnPropertyChanged("AxisDetails");
                OnPropertyChanged("GraphStartTime");
                OnPropertyChanged("GraphEndTime");
                OnPropertyChanged("GraphInterval");
                OnPropertyChanged("GraphDataPoints");
                OnPropertyChanged("GraphLegend");

                OnPropertyChanged("DowntimeVisibility");
                if (DowntimeVisibility == Visibility.Visible)
                {
                    OnPropertyChanged("CircularVisibility");
                    OnPropertyChanged("DowntimeDescription");
                    OnPropertyChanged("DowntimeBackground");
                    OnPropertyChanged("DowntimeForeground");
                }

                OnPropertyChanged("CellDowntimeGraphTitle");
                OnPropertyChanged("CellDowntimeGraphData");
            }

            _area_production_data = response.AreaProductionData;
            if (_area_production_data != null)
            {
                OnPropertyChanged("AreaDowntimeGraphTitle");
                OnPropertyChanged("AreaDowntimeGraphData");
                OnPropertyChanged("AreaPlantMetricsData");
                OnPropertyChanged("AreaUtilizationGraphData");

                _legend = new List<ProductionMeterGraphLegend>();
                if (_area_production_data.Legend != null)
                {
                    foreach (var lgd in _area_production_data.Legend)
                        _legend.Add(new ProductionMeterGraphLegend(lgd.Description, new SolidColorBrush(Infragistics.ColorConverter.FromString(lgd.Color))));
                    OnPropertyChanged("GraphLegend");
                }
            
            }

            var lookup = new Dictionary<int, CellButtonStatusItem>();
            foreach (var cbsi in response.CellStatus)
            {
                lookup.Add(cbsi.CellId, cbsi);
            }

            CellButtonStatusItem item;

            foreach (var cvm in _all_cells)
            {
                if (cvm.ID > 0)
                {
                    if (lookup.TryGetValue(cvm.ID, out item) && item.NoData == false)
                    {
                        cvm.RollupColor = item.RollupColor;
                        cvm.RollupFontColor = item.RollupFontColor;
                        cvm.AlarmColor = item.AlarmColor;
                        cvm.AlarmFontColor = item.AlarmFontColor;
                        cvm.Percent = item.Percent.ToString() + "%";
                        cvm.NoData = item.NoData;
                        if (response.IsCurrentShift)
                        {
                            cvm.Flash = item.Flash;
                            cvm.Offline = item.Offline;
                            cvm.TabletOffline = item.TabletOffline;
                            cvm.DisplayNameFontColor = (item.TabletOffline || item.Offline) ? "Yellow" : "#FFFFFFFF";
                        }
                        else
                        {
                            cvm.Flash = false;
                            cvm.Offline = false;
                            cvm.TabletOffline = false;
                            cvm.DisplayNameFontColor = "#FFFFFFFF";
                        }
                    }
                    else
                    {
                        cvm.TabletOffline = true;
                        cvm.Offline = true;
                        cvm.Flash = false;
                        cvm.Percent = "";
                        cvm.RollupColor = cvm.AlarmColor = cvm.AlarmFontColor = "#FFE7E3E7";
                        cvm.RollupFontColor = "#FFFFFFFF";
                        cvm.NoData = item.NoData;
                        cvm.DisplayNameFontColor = "#FFFFFFFF";
                    }
                }
            }

        }

        public bool selectCell(CellViewModel cvm)
        {

            if (cvm == null)
            {
                _cell_view_mode = CellViewMode.None;
                _selected_cell = cvm;
            }
            else if (cvm != _selected_cell)
            {
                _cell_view_mode = CellViewMode.Production;
                _selected_cell = cvm;
            }
            else if (_cell_view_mode == CellViewMode.Downtime)
            {
                _cell_view_mode = CellViewMode.None;
                _selected_cell = null;
            }
            else if (_cell_view_mode == CellViewMode.Production)
            {
                _cell_view_mode = CellViewMode.None;
                _selected_cell = null;
            }

            string title = TitleString.MainViewCentralTitle;
            if (_selected_cell != null)
            {
                title += " | " + _selected_cell.DisplayName;
                if (_selected_cell.TabletOffline)
                    title += " (Tablet Offline)";
                else if (_selected_cell.Offline)
                    title += " (Offline)";
            }
            PageTitle = title;

            OnPropertyChanged("ShowCellProductionControls");
            OnPropertyChanged("ShowAreaProductionControls");

            refreshUi(null, null);

            return _cell_view_mode != CellViewMode.None;

        }

        public void refreshUi(object sender, EventArgs e)
        {
            try
            {
                // Change max shift date at interval
                var currentDateTimeShift = GetCurrentAreaShiftItem(ShiftList);
                MaxShiftDate = GetMaxShiftDate(currentDateTimeShift);

                // If user selected current shift, set the current shift and current date
                if (_selectedCurrentShift)
                {
                    SelectedAreaShift = currentDateTimeShift;
                    ShiftDate = MaxShiftDate;
                }

                if (!_refreshing_ui || sender == null)  // sender is null when called by a UI action from the user and not a timer
                {
                    _refreshing_ui = true;
                    if (_refresh_ui_timer != null)
                        _refresh_ui_timer.Stop();
                    var input = new VisiCentralProvider.CellProductionData
                    {
                        AreaId = _area_id,
                        CellId = _selected_cell != null ? _selected_cell.ID : 0,
                        AreaShiftId = _selectedAreaShift != null ? _selectedAreaShift.AreaShiftId : 0,
                        ShiftDate = _shiftDate
                    };
                    DoAsync(VisiCentralProvider.GetCellProductionData, GetCellProductionDataCompleted, input);
                }
            }
            catch(Exception ex)
            {
                FileLog.Error("refreshUi() - ", ex);
            }

        }

        private void GetAreaShiftsCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var response = e.Result as GetDataResponse<IList<AreaShiftItem>>;
            IsBusy = false;

            if (response == null || !response.Success)
            {
                if (response != null)
                    ErrorMessage = response.Error.Description;
                return;
            }
            ShiftList = response.Data.Where(t => !t.Hidden)
                .OrderBy(t => t.StartTime).ToList();
            SelectedAreaShift = GetCurrentAreaShiftItem(ShiftList);

            // Get max shift date for current time and shift
            MaxShiftDate = GetMaxShiftDate(SelectedAreaShift);
            // Set ShiftDate to MaxShiftDate
            ShiftDate = MaxShiftDate;
            // Set _selectedCurrentShift to true
            _selectedCurrentShift = true;
        }

        #endregion

        #region Helpers

        private AreaShiftItem GetCurrentAreaShiftItem(IList<AreaShiftItem> shiftList)
        {
            var currentDateTime = DateTime.Now;
            
            // Set default value for selected area shift (current shift)
            // Find day shift
            var currentShift = shiftList.FirstOrDefault(t => currentDateTime.Date.Add(t.StartTime) <= currentDateTime
                && currentDateTime.Date.Add(t.EndTime) >= currentDateTime
                && t.StartTime < t.EndTime);
            if (currentShift == null)
            {
                // If day shift is null, then find the night shift (first part)
                currentShift = shiftList.FirstOrDefault(t => currentDateTime.Date.Add(t.StartTime) <= currentDateTime
                    && t.StartTime > t.EndTime);
                // Night shift, second part in the morning
                if (currentShift == null)
                    currentShift = shiftList.FirstOrDefault(t => currentDateTime.Date.Add(t.EndTime) >= currentDateTime
                        && t.StartTime > t.EndTime);
            }

            return currentShift;
        }

        private DateTime GetMaxShiftDate(AreaShiftItem currentShift)
        {
            var currentDateTime = DateTime.Now;

            try
            {

                // If current shift is day shift, return current date
                if (currentShift.StartTime < currentShift.EndTime)
                {
                    return currentDateTime.Date;
                }
                else
                {
                    // Night shift, first part in the night, return current date
                    if (currentDateTime >= currentDateTime.Date.Add(currentShift.StartTime))
                    {
                        return currentDateTime.Date;
                    }
                    else
                    {
                        // Night shift, second part in the morning
                        return currentDateTime.Date.AddDays(-1);
                    }
                }

            }
            catch (Exception ex)
            {
                FileLog.Error("GetMaxShiftDate() - ", ex);
            }

            return currentDateTime.Date; 
        }

        private void NavigateBack()
        {
            IsBusy = true;
            DoAsync(SecurityProvider.Logout, LogoutCompleted);
        }

        private void OnNextShift(object obj)
        {
            // Check if it is possible to go to the next shift
            var currentShiftIndex = _shiftList.IndexOf(_selectedAreaShift);
            if (currentShiftIndex != -1)
            {
                AreaShiftItem nextShift;
                if (currentShiftIndex != _shiftList.Count - 1)
                {
                    nextShift = _shiftList[currentShiftIndex + 1];
                    if (DateTime.Now < _shiftDate.Date.Add(nextShift.StartTime))
                    {
                        // MessageBox.Show(CANNOT_NAVIGATE_TO_FUTURE_SHIFT, "Error");
                    }
                    else
                    {
                        _selectedAreaShift = nextShift;
                        OnPropertyChanged("SelectedAreaShift");
                        SetSelectedCurrentShift(_selectedAreaShift, ShiftDate);
                        refreshUi(null, null);
                    }
                }
                else
                {
                    nextShift = _shiftList[0];
                    var nextDateMove = _shiftDate.AddDays(1);
                    if (DateTime.Now < nextDateMove.Date.Add(nextShift.StartTime))
                    {
                        // MessageBox.Show(CANNOT_NAVIGATE_TO_FUTURE_SHIFT, "Error");
                    }
                    else
                    {
                        _selectedAreaShift = nextShift;
                        OnPropertyChanged("SelectedAreaShift");
                        _shiftDate = nextDateMove;
                        OnPropertyChanged("ShiftDate");
                        SetSelectedCurrentShift(_selectedAreaShift, ShiftDate);
                        refreshUi(null, null);
                    }
                }
            }
        }

        private void OnPreviousShift(object obj)
        {
            var currentShiftIndex = _shiftList.IndexOf(_selectedAreaShift);
            if (currentShiftIndex != -1 && _shiftList.Count > 0)
            {
                AreaShiftItem previousShift;
                if (currentShiftIndex != 0)
                {
                    previousShift = _shiftList[currentShiftIndex - 1];
                }
                else
                {
                    previousShift = _shiftList[ShiftList.Count - 1];
                    var nextDateMove = _shiftDate.AddDays(-1);
                    _shiftDate = nextDateMove;
                    OnPropertyChanged("ShiftDate");
                }
                _selectedAreaShift = previousShift;
                OnPropertyChanged("SelectedAreaShift");
                _selectedCurrentShift = false;
                refreshUi(null, null);
            }
        }

        private void SetSelectedCurrentShift(AreaShiftItem selectedAreaShift, DateTime shiftDate)
        {
            var currentDateTimeShift = GetCurrentAreaShiftItem(ShiftList);
            if (ShiftDate.Date == GetMaxShiftDate(currentDateTimeShift)
                && currentDateTimeShift.Equals(_selectedAreaShift))
                _selectedCurrentShift = true;
            else
                _selectedCurrentShift = false;
        }

        #endregion

        #endregion

        #region Navigation Framwork
        public override void OnNavigate(object obj)
        {
            _refresh_ui_timer.Start();
        }

        public override void OnLeave()
        {
            _refresh_ui_timer.Stop();
        }

        public void OnExit()
        {
            NavigationManager.CloseProgram();
        }

        public void OnAnalysis()
        {
            _refresh_ui_timer.Stop();
            NavigationManager.NavigateTo(new AnalysisView(), null);
        }
        #endregion

        #region ProductionInterface

        #region Properties

        public Brush HeaderTextBrush { get { return null; } }
        public Brush HeaderBrush { get { return null; } }
        public bool Offline { get; set; }
        public bool RedrawError { get; set; }

        public DateTime GraphStartTime { get { return _cell_production_data != null ? _cell_production_data.StartTime : DateTime.Now; } }
        public DateTime GraphEndTime { get { return _cell_production_data != null ? _cell_production_data.EndTime : DateTime.Now; } }
        public ObservableCollection<ProductionMeterDataPoint> GraphDataPoints { get { return _cell_production_data != null ? _cell_production_data.GraphData : null; } }
        public int GraphInterval { get { return _cell_production_data != null ? _cell_production_data.ProductionMeterWidth : 60; } }
        public Visibility Visibility { get; set; }
        public List<AxisDetailItem> AxisDetails { get { return _cell_production_data != null ? _cell_production_data.Axis : null; } }
        public List<ProductionMeterGraphLegend> GraphLegend
        {
            get { return _legend; }
        }

        public Visibility CountDownTimerVisibility { get { return Visibility.Collapsed; } set {} }
        public TimeSpan CountDownTime { get; set; }

        public Visibility CircularVisibility { get { return Visibility.Collapsed; } set { } }
        public Visibility PressToChangeVisibility { get { return Visibility.Collapsed; } }
        public Visibility DowntimeVisibility { get { return (_cell_production_data != null && !string.IsNullOrEmpty(_cell_production_data.DowntimeDescription) ? Visibility.Visible : Visibility.Collapsed); } }
        public string DowntimeDescription { get { return _cell_production_data != null ? _cell_production_data.DowntimeDescription : ""; } }
        public Brush DowntimeBackground
        {
            get 
            {
                Brush brush;
                if (_cell_production_data != null)
                    brush = new SolidColorBrush(Infragistics.ColorConverter.FromString(_cell_production_data.DowntimeBackground));
                else
                    brush = new SolidColorBrush(Colors.White);
                return brush;
            }
        }
        public Brush DowntimeForeground
        {
            get
            {
                Brush brush;
                if (_cell_production_data != null)
                    brush = new SolidColorBrush(Infragistics.ColorConverter.FromString(_cell_production_data.DowntimeForeground));
                else
                    brush = new SolidColorBrush(Colors.White);
                return brush;
            }
        }
        public GridLength DowntimeColumn1 { get { return new GridLength(1, GridUnitType.Star); } }
        public GridLength DowntimeColumn2 { get { return new GridLength(1, GridUnitType.Auto); } }
        public GridLength DowntimeColumn3 { get { return new GridLength(1, GridUnitType.Star); } }

        public string TargetCycleTime { get { return _cell_production_data != null ? _cell_production_data.TargetCycleTime : ""; } }
        public string TargetLoadUnloadTime { get { return _cell_production_data != null ? _cell_production_data.TargetLoadUnloadTime : ""; } }
        public int TargetLoadUnloadSecs { get { return 30; } }
        public string AverageCycleTime
        {
            get { return _cell_production_data != null ? _cell_production_data.AverageCycleTime : ""; }
            set { /* nada */ }
        }
        public string AverageLoadUnloadTime
        {
            get { return _cell_production_data != null ? _cell_production_data.AverageLoadUnloadTime : ""; }
            set { /* nada */ }
        }

        public string CurrentSku { get { return _cell_production_data != null ? _cell_production_data.CurrentSku : ""; } }
        public string CurrentWorkOrder { get { return _cell_production_data != null ? _cell_production_data.CurrentWorkOrder : ""; } }
        public string CurrentPass { get { return _cell_production_data != null ? _cell_production_data.CurrentPass : ""; } }
        public string CurrentQuantity { get { return _cell_production_data != null ? _cell_production_data.CurrentQuantity : ""; } }
        public string CurrentRemaining { get { return _cell_production_data != null ? _cell_production_data.CurrentRemaining : ""; } }
        public string NextSku { get { return _cell_production_data != null ? _cell_production_data.NextSku : ""; } }
        public string NextWorkOrder { get { return _cell_production_data != null ? _cell_production_data.NextWorkOrder : ""; } }
        public string NextPass { get { return _cell_production_data != null ? _cell_production_data.NextPass : ""; } }
        public string NextQuantity { get { return _cell_production_data != null ? _cell_production_data.NextQuantity : ""; } }
        public string NextRemaining { get { return _cell_production_data != null ? _cell_production_data.NextRemaining : ""; } }

        public string Operator { get { return _cell_production_data != null ? _cell_production_data.Operator : ""; } }

        public string CellDowntimeGraphTitle { get { return _cell_production_data != null ? _cell_production_data.DowntimeGraphTitle : ""; } }
        public List<DowntimeGraphDataItem> CellDowntimeGraphData { get { return _cell_production_data != null ? _cell_production_data.DowntimeGraphData : null; } }

        public string AreaDowntimeGraphTitle { get { return _area_production_data != null ? _area_production_data.DowntimeGraphTitle : ""; } }
        public List<DowntimeGraphDataItem> AreaDowntimeGraphData { get { return _area_production_data != null ? _area_production_data.DowntimeGraphData : null; } }
        public List<GraphDataItem> AreaUtilizationGraphData { get { return _area_production_data != null ? _area_production_data.UtilizationGraphData : null; } }
        public PlantMetricsDataItem AreaPlantMetricsData { get { return _area_production_data != null ? _area_production_data.PlantMetrics : null; } }
        #endregion

        #region Methods

        public bool getAlarmSettings(List<int> percentages, List<Brush> foregrounds, List<Brush> backgrounds) { return false; }
        public void showDowntimeDialog(bool is_from_process_visibox_events, bool hide_progress_bar) { }
        public void handleCircularProgressUpdates(object send, EventArgs args) { }

        #endregion

        #endregion

    }
}
